from django.db import models
from user.models import User
from ckeditor_uploader.fields import RichTextUploadingField
import jieba
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import os
import hashlib
import datetime
from log.my_cache import lru_cache

# 聊天记录


class ChatRecord(models.Model):
    # 发送者
    sender = models.ForeignKey(User, on_delete=models.CASCADE, db_column='发送者',
                               verbose_name='发送者', help_text='发送者', related_name='发送者')

    # 接收者
    receiver = models.ForeignKey(User, on_delete=models.CASCADE, db_column='接收者',
                                 verbose_name='接收者', help_text='接收者', related_name='接收者')

    # 内容
    # content=models.TextField(max_length=1000,db_column='内容',verbose_name='内容',help_text='内容')
    content = RichTextUploadingField(
        max_length=1000, db_column='内容', verbose_name='内容', help_text='内容')

    # 是否已读
    is_read = models.BooleanField(
        default=False, db_column='是否已读', verbose_name='是否已读', help_text='是否已读', blank=True)

    # 是否撤回
    is_return = models.BooleanField(
        default=False, db_column='是否撤回', verbose_name='是否撤回', help_text='是否撤回'
    )

    # 自动回复
    auto_reply = models.BooleanField(
        default=False, db_column='自动回复', verbose_name='自动回复', help_text='当前消息是否是自动回复的。'
    )

    # 时间
    time = models.DateTimeField(
        auto_now=True, db_column='时间', verbose_name='时间', help_text='时间')

    class Meta:
        db_table = '聊天记录'
        verbose_name_plural = verbose_name = db_table

    @classmethod
    def create_record(cls, sender, receiver, content):
        #回复了一条消息，忙录值减一
        sender.busy_score -= 1
        #接收到了一条消息，忙录值加一
        receiver.busy_score += 1
        new_obj = cls()
        new_obj.sender = sender
        new_obj.receiver = receiver
        new_obj.content = content
        new_obj.save()
        return new_obj

    @classmethod
    def get_by_pk(cls, pk):
        return cls.objects.filter(id=pk).first()

    # 获取指定时段内的高频短语
    @classmethod
    @lru_cache(size=128, expires_check=True, expires=60*60)
    def get_high_rate_words(cls, start_time, end_time):
        with open('chat/stopwords.txt', 'r', encoding='utf8') as f:
            stop_words = set(f.read().split('\n'))

        content_list = [
            cr.content
            for cr in cls.objects.filter(time__range=(start_time, end_time))
        ]
        words = jieba.lcut(' '.join(content_list))
        word_dict = {}
        for word in words:
            if word not in stop_words:
                word_dict[word] = word_dict.get(word, 0) + 1

        data = {
            item[0]: item[1]
            # 前100个高频词
            for item in sorted(word_dict.items(), key=lambda a: -a[1])[:100]
        }

        data_path = cls.draw_wordcloud(data)

        return (data, data_path)

    @staticmethod
    def draw_wordcloud(data: dict):
        # 绘制词云
        my_cloud = WordCloud(
            background_color='white',  # 设置背景颜色  默认是black
            width=900, height=600,
            max_words=100,  # 词云显示的最大词语数量
            font_path='static/fonts/simhei.ttf',  # 设置字体  显示中文
            max_font_size=99,  # 设置字体最大值
            min_font_size=16,  # 设置子图最小值
            random_state=50  # 设置随机生成状态，即多少种配色方案
        ).fit_words(data)

        # 显示生成的词云图片
        plt.imshow(my_cloud)
        # 显示设置词云图中无坐标轴
        plt.axis('off')

        file_name = hashlib.sha256(
            bytes(str(data), encoding='utf8')).hexdigest()
        now = datetime.datetime.now()
        year, month, day = now.year, now.month, now.day
        _dir = os.path.join('media', 'imgs', str(year), str(month), str(day))
        if not os.path.isdir(_dir):
            os.makedirs(_dir)
        path = os.path.join(_dir, f'{file_name}.jpg')
        plt.savefig(path)

        return path


# 词语回复对应表
class WordReplyMap(models.Model):
    # 关键词
    word = models.CharField(max_length=20, unique=True,
                            db_column='关键词', verbose_name='关键词', help_text='关键词')

    # 回复
    reply = models.TextField(db_column='回复', verbose_name='回复', help_text='回复')

    # 时间
    time = models.DateTimeField(
        auto_now=True, db_column='时间', verbose_name='时间', help_text='时间')

    class Meta:
        db_table = '词语-回复映射'
        verbose_name_plural = verbose_name = db_table

    @classmethod
    def get_by_pk(cls, pk):
        return cls.objects.filter(id=pk).first()

    # 在问题中搜索关键词
    @classmethod
    def match(cls, requestion):
        for wr in cls.objects.all():
            if wr.word in requestion:
                return wr.reply

    @classmethod
    def get_by_word(cls, word):
        return cls.objects.filter(word=word).first()


# 图片上传
class Img(models.Model):

    # 上传者
    uploader = models.ForeignKey(
        User, on_delete=models.CASCADE, db_column='上传者', verbose_name='上传者', help_text='上传者')

    # 图片
    img = models.ImageField(upload_to='imgs/%Y/%m/%d',
                            db_column='位置', verbose_name='位置', help_text='位置')

    # 时间
    time = models.DateTimeField(
        auto_now=True, db_column='时间', verbose_name='时间', help_text='时间')

    class Meta:
        db_table = '图片'
        verbose_name_plural = verbose_name = db_table
